package cn.iocoder.yudao.module.pay.dal.mysql.order;

import cn.iocoder.yudao.framework.common.enums.pay.PayorderDetailStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDetailDO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.ibatis.annotations.Mapper;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime;
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_DETAIL_WAITING_PAY;


/**
 * 订单支付详情表
 * (PayOrderDetail)表数据库访问层
 *
 * @author makejava
 * @since 2025-03-22 15:12:37
 */
@Mapper
public interface PayOrderDetailMapper extends BaseMapperX<PayOrderDetailDO> {

    default int insertDetail (PayOrderDetailDO detailDO) {
         long count = selectCount(new LambdaQueryWrapper<PayOrderDetailDO>()
                .eq(PayOrderDetailDO::getPayId, detailDO.getPayId())
                .eq(PayOrderDetailDO::getStatus, PayorderDetailStatusEnum.WAITING.getStatus()));
         if (count > 0) {
             throw exception(PAY_ORDER_DETAIL_WAITING_PAY);
         }
         if (detailDO.getExpireTime() == null) {
             detailDO.setExpireTime(addTime(Duration.ofMinutes(5)));
         }
         return insert(detailDO);
    }


    default PayOrderDetailDO selectByNo(String outTradeNo) {
        return selectOne(PayOrderDetailDO::getNo, outTradeNo);
    }


    default int updateByIdAndStatus(Long id, Integer status, PayOrderDetailDO update) {
        return update(update, new LambdaQueryWrapper<PayOrderDetailDO>()
                .eq(PayOrderDetailDO::getId, id).eq(PayOrderDetailDO::getStatus, status));
    }

    default List<PayOrderDetailDO> selectListByOrderIdAndStatus(Long id, Integer status) {
        return selectList(PayOrderDetailDO::getPayId,id,PayOrderDetailDO::getStatus,status);
    }

    default List<PayOrderDetailDO> selectListByOrderId(Long orderId) {
        return selectList(PayOrderDetailDO::getPayId, orderId);
    }

    default List<PayOrderDetailDO> selectListByStatusAndCreateTimeGe(Integer status, LocalDateTime minCreateTime) {
        return selectList(new LambdaQueryWrapper<PayOrderDetailDO>()
                .eq(PayOrderDetailDO::getStatus, status)
                .ge(PayOrderDetailDO::getCreateTime, minCreateTime));
    }

    default List<PayOrderDetailDO> selectListByStatusAndExpireTimeLt(Integer status, LocalDateTime now) {
        return selectList(new LambdaQueryWrapper<PayOrderDetailDO>()
                .eq(PayOrderDetailDO::getStatus, status)
                .lt(PayOrderDetailDO::getExpireTime, now)
                .orderByAsc(PayOrderDetailDO::getExpireTime));
    }
}

